package com.guoxin.concurrentprogramming.chapter3.threadpool;


import java.util.concurrent.*;

/**
 * @author guoxin
 * @date 2019/7/16
 */
public class TraceThreadPoolExecutor extends ThreadPoolExecutor {
    public TraceThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    @Override
    public void execute(Runnable command) {
        Runnable wrapThread = wrap(command, clientTrace(), Thread.currentThread().getName());
        super.execute(wrapThread);
    }

    @Override
    public Future<?> submit(Runnable task) {
        Runnable wrapThread = wrap(task, clientTrace(), Thread.currentThread().getName());
        return super.submit(wrapThread);
    }

    private Exception clientTrace() {
        return new Exception("Client stack trace");
    }

    private Runnable wrap(final Runnable runnable, final Exception clientStack, String clientThreadName) {
        return () -> {
            try {
                runnable.run();
            } catch (Exception e) {
                clientStack.printStackTrace();
                throw e;
            }
        };
    }


    public static void main(String[] args) {
        ExecutorService service = new TraceThreadPoolExecutor(10, 20, 0L, TimeUnit.MICROSECONDS, new SynchronousQueue<>());

        for(int i=0;i<5;i++){
            service.execute(new DivTask(100,i));
        }
    }
}
